Back - Trigger

Software Projects - Basic JavaScript App

Lacrimae rerum. Memento mori. Memento vivere.

Compound Returns Calculator

A compounded return refers to the process where the earnings generated by an investment are reinvested and themselves generate additional earnings over time, which leads to exponential growth due to the effect of returns on both the initial principal and accumulated earnings. Depending on what is being compounded and given enough time, this has been described the "most powerful force in the universe" (often attributed to Albert Einstein). At the end of the day, those who understand it will earn it and those who do not understand it will pay it (although it is not a zero-sum game).

How To Play

It is simple to calculate compound return on an initial principal, but it can become more complicated when accounting for additional monthly contributions (loop was actually used instead of the formula).

Formula to calculate the accumulated amount from compound return and additional monthly contributions:
\[\begin{gather*} A = P_{i} \left(1 + \frac{r}{n}\right) ^ {nt} + \frac{P_{m} \left(\left(1 + r/n\right)^{nt} - 1\right)}{r/n} \end{gather*}\]

Basic Program Design

A standard calculation of compound return was developed for the project. The application consists of inputs for the initial principal, additional monthly contributions, number of months for the period, annual rate of the return, and variance in the annual rate of the return. The variance in the annual rate of the return is used to calculate upper and lower bounds in addition to the expected value. The final amounts for these values are reported and Plotly is used to create a graph with the compounded return over the number of months for the period.

Design of the HTML elements used for the collection buttons, quote box, and transitioning functions:
				<form id="returns-form">
				    <label class = "input-label" for = "initial-principal">Initial Principal:</label>
				    <input class = "input-single" type = "number" id = "initial-principal" step = "1" min = "0" value = "1000" required>
				    <label class = "input-label" for = "monthly-contribution">Monthly Contribution:</label>
				    <input class = "input-single" type = "number" id = "monthly-contribution" step = "1" min = "0" value = "100" required>
				    <label class = "input-label" for = "total-months">Total Months:</label>
				    <input class = "input-single" type = "number" id = "total-months" step = "1" min = "0" value = "300" required>
				    <label class = "input-label" for = "annual-rate">Annual Rate:</label>
				    <input class = "input-single" type = "number" id = "annual-rate" step = "0.01" min = "0" value = "0.1" required>
				    <label class = "input-label" for = "variance-rate">Rate Variance:</label>
				    <input class = "input-single" type = "number" id = "variance-rate" step = "0.01" min = "0" value = "0.02" required>
				    <div class = "buttonsGroup">
				        <button class = "button" type = "button" onclick = "calculateCompoundReturns()">Calculate</button>
				    </div>
				</form>
				<div id = "results-values"></div>
				<div id = "results-chart"></div>
Design of the JavaScript to follow the game rules using the collection buttons, quote box, and transitioning functions:
				function calculateCompoundReturns() {
				    const startingAmount = parseFloat(document.getElementById('initial-principal').value);
				    const monthlyContribution = parseFloat(document.getElementById('monthly-contribution').value);
				    const totalMonths = parseInt(document.getElementById('total-months').value);
				    const annualRate = parseFloat(document.getElementById('annual-rate').value);
				    const variance = parseFloat(document.getElementById('variance-rate').value);
				
				    const monthlyRate = annualRate / 12;
				    const monthlyRateUpper = (annualRate + variance) / 12;
				    const monthlyRateLower = (annualRate - variance) / 12;
				
				    const months = [];
				    const balances = [];
				    const upperBalances = [];
				    const lowerBalances = [];
				
				    let balance = startingAmount;
				    let upperBalance = startingAmount;
				    let lowerBalance = startingAmount;
				
				    for (let month = 1; month <= totalMonths; month++) {
				        balance = (balance + monthlyContribution) * (1 + monthlyRate);
				        upperBalance = (upperBalance + monthlyContribution) * (1 + monthlyRateUpper);
				        lowerBalance = (lowerBalance + monthlyContribution) * (1 + monthlyRateLower);
				
				        months.push(month);
				        balances.push(balance);
				        upperBalances.push(upperBalance);
				        lowerBalances.push(lowerBalance);
				    }
				
				    const traceExpected = {
				        x: months,
				        y: balances,
				        type: 'line',
				        name: 'Expected Value',
				        line: {
				            shape: "spline",
				        },
				    };
				
				    const traceUpper = {
				        x: months,
				        y: upperBalances,
				        type: 'line',
				        name: 'Upper Bound',
				        line: {
				            shape: "spline",
				        },
				    };
				
				    const traceLower = {
				        x: months,
				        y: lowerBalances,
				        type: 'line',
				        name: 'Lower Bound',
				        line: {
				            shape: "spline",
				        },
				    };
				
				    const layout = {}
				
				    Plotly.newPlot('results-chart', [traceExpected, traceUpper, traceLower], layout);
				
				    document.getElementById('results-values').innerHTML = `
				        <div&lgt;Final Lower Bound Balance: ${lowerBalances[lowerBalances.length - 1].toFixed(2)}</div&lgt;
				        <div&lgt;Final Expected Balance: ${balances[balances.length - 1].toFixed(2)}</div&lgt;
				        <div&lgt;Final Upper Bound Balance: ${upperBalances[upperBalances.length - 1].toFixed(2)}</div&lgt;
				    `;
				}
				
				calculateCompoundReturns();